package com.boot.proofing.common.db;/**
 * @description
 * @autor xbwu on 2018/5/25.
 */

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.boot.core.common.util.SpringUtils;
import com.boot.proofing.common.util.WebUtils;
import com.boot.proofing.mpweb.base.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.ApplicationContext;

import java.util.Date;
import java.util.Map;


/**
 * mybatis plus注入公共字段自动填充,任选注入方式即可
 * 注意：自动填充必须在字段上搭配    @TableField(fill = FieldFill.具体填充执行的方法) 注解才行
 * 非BaseMpEntity字段策略，参照 UserFieldStrategy 进行注入
 *
 * @author xbwu
 * @create 2018-05-25
 **/
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {


    /**
     * BaseMpEntity共有字段填充（新增时）
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        User currentUser = WebUtils.getUser();
        //操作者
        setFieldValByName("operator", currentUser == null ? "system" : currentUser.getId().toString(), metaObject);
        setFieldValByName("createDateTime", new Date(), metaObject);
        setFieldValByName("modifyDateTime", new Date(), metaObject);
        //默认逻辑删除值为0，就是未被删除的意思
        setFieldValByName("isDelete", "0", metaObject);
        //是否有效设置
        Boolean valid = (Boolean) getFieldValByName("valid", metaObject);
        if (valid == null) {
            setFieldValByName("valid", true, metaObject);
        }
        //乐观锁初始值
        setFieldValByName("version", 0L, metaObject);
        injectInsertFieldStrategy(metaObject);
    }

    /**
     * BaseMpEntity共有字段填充（更新时）
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        User currentUser = WebUtils.getUser();
        //操作者
        setFieldValByName("operator", currentUser == null ? "system" : currentUser.getId().toString(), metaObject);
        setFieldValByName("modifyDateTime", new Date(), metaObject);
        //是否有效设置
        Boolean valid = (Boolean) getFieldValByName("valid", metaObject);
        if (valid == null) {
            setFieldValByName("valid", true, metaObject);
        }
        injectUpdateFieldStrategy(metaObject);
    }

    /**
     * 注入其他实体的插入策略
     *
     * @param metaObject
     */
    private void injectInsertFieldStrategy(MetaObject metaObject) {
        ApplicationContext wac = SpringUtils.getApplicationContext();
        Map<String, CustomerMetaObjectHandler> maps = wac.getBeansOfType(CustomerMetaObjectHandler.class);
        //用户表策略
        for (CustomerMetaObjectHandler cmo : maps.values()) {
            try {
                cmo.insertFill(metaObject);
            } catch(Exception e) {
                log.error("自定义mybatis插入策略：{} 出现问题", cmo.getClass());
            }
        }
    }

    /**
     * 注入其他实体的更新策略
     *
     * @param metaObject
     */
    private void injectUpdateFieldStrategy(MetaObject metaObject) {
        ApplicationContext wac = SpringUtils.getApplicationContext();
        Map<String, CustomerMetaObjectHandler> maps = wac.getBeansOfType(CustomerMetaObjectHandler.class);
        //用户表策略
        for (CustomerMetaObjectHandler cmo : maps.values()) {
            try {
                cmo.updateFill(metaObject);
            } catch(Exception e) {
                log.error("自定义mybatis插入策略：{} 出现问题", cmo.getClass());
            }
        }
    }
}